﻿//===============================================================================
// Microsoft Innovation Centre - Western Europe
// Copyright (c) 2008 Microsoft Corporation. All rights reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================

using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Microsoft.WVB.Framework;
using Microsoft.WVB.Silverlight.Infrastructure;
using System.Windows.Media.Animation;
using System;

namespace Microsoft.WVB.UI
{
    [TemplatePart(Name = MediaPlayer.RootElementName, Type = typeof(FrameworkElement)),
    TemplatePart(Name = MediaPlayer.MediaElementName, Type = typeof(Panel)),
    TemplatePart(Name = MediaPlayer.BufferAnimationElementName, Type = typeof(Spinner)),
    TemplatePart(Name = MediaPlayer.CaptionElementName, Type = typeof(TextBlock)),
    TemplatePart(Name = MediaPlayer.MediaControlsElementName, Type = typeof(MediaControls))]
    public class MediaPlayer : Control
    {
        private const string RootElementName = "RootElement";
        private const string MediaElementName = "MediaPlaceholder";
        private const string BufferAnimationElementName = "BufferAnimationElement";
        private const string CaptionElementName = "CaptionElement";
        private const string MediaControlsElementName = "MediaControlsElement";
     
        public bool IsFullScreen
        {
            get { return (bool)GetValue(IsFullScreenProperty); }
            set { SetValue(IsFullScreenProperty, value); }
        }
        public static readonly DependencyProperty IsFullScreenProperty = null;

        public bool IsBuffering
        {
            get { return (bool)GetValue(IsBufferingProperty); }
            set { SetValue(IsBufferingProperty, value); }
        }
        public static readonly DependencyProperty IsBufferingProperty = null;

        public FrameworkElement RootElement
        {
            get { return _RootElement; }
            set { _RootElement = value; }
        }
        private FrameworkElement _RootElement;

        public Panel MediaPlaceholder
        {
            get { return _MediaPlaceholder; }
            set { _MediaPlaceholder = value; }
        }
        private Panel _MediaPlaceholder;

        public Spinner BufferAnimationElement
        {
            get { return _BufferAnimationElement; }
            set { _BufferAnimationElement = value; }
        }
        private Spinner _BufferAnimationElement;

        public TextBlock Caption
        {
            get { return _Caption; }
            set { _Caption = value; }
        }
        private TextBlock _Caption;

        public MediaControls MediaControls
        {
            get { return _MediaControls; }
            set { _MediaControls = value; }
        }
        private MediaControls _MediaControls;

        public IPlayerModel ViewModel { get; private set; }

        static MediaPlayer()
        {
            IsBufferingProperty = DependencyProperty.Register("IsBuffering", typeof(bool), typeof(MediaPlayer), new PropertyMetadata(MediaPlayer.OnIsBufferingChanged));
        }

        public MediaPlayer()
        {
            this.DefaultStyleKey = typeof(MediaPlayer);

            if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
            {
                //GetCreate important when we share a model
                ViewModel = IoC.GetCreate<IPlayerModel>();
                DataContext = ViewModel;

                Binding bufferBinding = new Binding("Buffering");
                bufferBinding.Source = ViewModel;
                bufferBinding.Mode = BindingMode.OneWay;
                this.SetBinding(IsBufferingProperty, bufferBinding);

                ////Binding fullScreenBinding = new Binding("IsFullScreen");
                ////fullScreenBinding.Source = ViewModel;
                ////fullScreenBinding.Mode = BindingMode.OneWay;
                ////this.SetBinding(IsFullScreenProperty, fullScreenBinding);

                Application.Current.Host.Content.FullScreenChanged += new System.EventHandler(Content_FullScreenChanged);
            }
        }

        private void Content_FullScreenChanged(object sender, System.EventArgs e)
        {
            if (Application.Current.Host.Content.IsFullScreen)
            {
                this.OnFullScreenEnter();
            }
            else
            {
                this.OnFullScreenLeave();
            }
        }

        internal void ChangeVisualState()
        {
            this.ChangeVisualState(true);
        }

        internal void ChangeVisualState(bool useTransition)
        {

        }

        ////private static void OnIsFullScreenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        ////{
        ////    if ((bool)e.NewValue)
        ////    {
        ////        ((MediaPlayer)d).OnFullScreenEnter();
        ////    }
        ////    else
        ////    {
        ////        ((MediaPlayer)d).OnFullScreenLeave();
        ////    }                      
        ////}

        private static void OnIsBufferingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((MediaPlayer)d).OnIsBufferingChanged((bool)e.OldValue, (bool)e.NewValue);
        }

        public virtual void OnFullScreenLeave()
        {
            if (MediaPlaceholder != null)
            {
   
            }

            if (this.MediaControls != null)
            {                
                this.MediaControls.MouseEnter -= new System.Windows.Input.MouseEventHandler(MediaControls_MouseEnter);
                this.MediaControls.MouseLeave -= new System.Windows.Input.MouseEventHandler(MediaControls_MouseLeave);

                this.MediaControls.Opacity = 1.0;
            }
        }

        public virtual void OnFullScreenEnter()
        {
            if (MediaPlaceholder != null)
            {
                this.MediaControls.MouseEnter += new System.Windows.Input.MouseEventHandler(MediaControls_MouseEnter);
                this.MediaControls.MouseLeave += new System.Windows.Input.MouseEventHandler(MediaControls_MouseLeave);
            }

            this.MediaControls.Opacity = 0.2;
        }

        void MediaControls_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            Storyboard popDownStorybord = Application.Current.Resources["MediaControls_PopDown"] as Storyboard;

            if (popDownStorybord == null)
            {
                // Create a duration of 0.5 seconds.
                Duration duration = new Duration(TimeSpan.FromSeconds(0.5));

                // Create two DoubleAnimations and set their properties.
                DoubleAnimation animateOpacityDown = new DoubleAnimation();

                animateOpacityDown.Duration = duration;
                popDownStorybord = new Storyboard();

                popDownStorybord.Duration = duration;

                popDownStorybord.Children.Add(animateOpacityDown);

                Storyboard.SetTarget(animateOpacityDown, this.MediaControls);
                             
                Storyboard.SetTargetProperty(animateOpacityDown, new PropertyPath("(FrameworkElement.Opacity)"));

                animateOpacityDown.To = 0.2;

                // Make the Storyboard a resource.

                Application.Current.Resources.Add("MediaControls_PopDown", popDownStorybord);
            }

            // Begin the animation.
            popDownStorybord.Begin();

        }

        void MediaControls_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            Storyboard popUpStorybord = Application.Current.Resources["MediaControls_PopUp"] as Storyboard;

            if (popUpStorybord == null)
            {
                // Create a duration of 2 seconds.
                Duration duration = new Duration(TimeSpan.FromSeconds(0.5));

                // Create two DoubleAnimations and set their properties.
                DoubleAnimation animateOpacityUp = new DoubleAnimation();

                animateOpacityUp.Duration = duration;
                popUpStorybord = new Storyboard();

                popUpStorybord.Duration = duration;

                popUpStorybord.Children.Add(animateOpacityUp);

                Storyboard.SetTarget(animateOpacityUp, this.MediaControls);

                Storyboard.SetTargetProperty(animateOpacityUp, new PropertyPath("(FrameworkElement.Opacity)"));

                animateOpacityUp.To = 1.0;

                // Make the Storyboard a resource.

                Application.Current.Resources.Add("MediaControls_PopUp", popUpStorybord);
            }

            // Begin the animation.
            popUpStorybord.Begin();

        }

        protected virtual void OnIsBufferingChanged(bool oldValue, bool newValue)
        {
            if (this.BufferAnimationElement != null)
            {
                if ((bool)newValue)
                {
                    this.BufferAnimationElement.Animation.Begin();
                }
                else
                {
                    this.BufferAnimationElement.Animation.Stop();
                }
            }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this.BufferAnimationElement = base.GetTemplateChild(MediaPlayer.BufferAnimationElementName) as Spinner;
            this.MediaPlaceholder = base.GetTemplateChild(MediaPlayer.MediaElementName) as Panel;
            this.RootElement = base.GetTemplateChild(MediaPlayer.RootElementName) as FrameworkElement;
            this.Caption = base.GetTemplateChild(MediaPlayer.CaptionElementName) as TextBlock;
            this.MediaControls = base.GetTemplateChild(MediaPlayer.MediaControlsElementName) as MediaControls;

            if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
            {
                if (this.MediaPlaceholder != null)
                {
                    this.MediaPlaceholder.Children.Add(ViewModel.DisplaySurface);
                    ViewModel.DisplaySurface.SetValue(Grid.RowProperty, 0);
                }

                if (this.BufferAnimationElement != null)
                {
                    Binding bVisibleBinding = new Binding("Buffering");
                    bVisibleBinding.Source = ViewModel;
                    bVisibleBinding.Mode = BindingMode.OneWay;
                    bVisibleBinding.Converter = new VisibilityConverter();

                    this.BufferAnimationElement.SetBinding(VisibilityProperty, bVisibleBinding);
                }

                if (this.Caption != null)
                {
                    Binding captionBinding = new Binding("CaptionText");
                    captionBinding.Source = ViewModel;
                    captionBinding.Mode = BindingMode.OneWay;

                    this.Caption.SetBinding(TextBlock.TextProperty, captionBinding);
                }
            }
        }
    }
}
